package com.example.javaapiclient.service.impl;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.indices.*;
import co.elastic.clients.json.JsonData;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import com.alibaba.fastjson.JSON;
import com.example.javaapiclient.annotations.ESDocument;
import com.example.javaapiclient.service.ElasticsearchIndexService;
import com.example.javaapiclient.utils.ElasticSearchHelpUtils;
import com.example.javaapiclient.utils.EmptyUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.io.Reader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;

/**
 * 索引数据库的创建、删除、存在
 **/
@Service
@Slf4j
public class ElasticsearchIndexServiceImpl<T> implements ElasticsearchIndexService<T> {

    @Resource
    private ElasticsearchClient client;

    @Resource
    private ElasticSearchHelpUtils<T> elasticSearchHelpUtils;

    /**
     * 判断索引是否存在
     * @param clazz
     * @return
     * @throws Exception
     */
    @Override
    public boolean exists(Class<T> clazz) throws Exception{
        String indexName = elasticSearchHelpUtils.getOnlyIndexName(clazz);
        ExistsRequest existsRequest = new ExistsRequest.Builder().index(indexName).build();
        BooleanResponse booleanResponse = client.indices().exists(existsRequest);
        return booleanResponse.value();
    }

    @Override
    public Boolean createIndex(Class<T> clazz) throws Exception{
        ESDocument document = clazz.getAnnotation(ESDocument.class);
        String indexName = elasticSearchHelpUtils.getOnlyIndexName(clazz);

        if(Boolean.FALSE.equals(document.createIndex())){
            return false;
        }

        Reader readerMapping = new StringReader(JSON.toJSONString(elasticSearchHelpUtils.getMapping(clazz)));

        Map<String,Alias> aliasMap = new HashMap<>();

        //设置索引别名
        if (EmptyUtil.isNotEmpty(document.indexAliasesName())){
            Alias alias = new Alias.Builder().isWriteIndex(true).build();
            aliasMap.put(document.indexAliasesName(),alias);
        }

        CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest->createIndexRequest
                .index(indexName)
                .aliases(aliasMap)
                .settings(indexSettings->indexSettings
                        .refreshInterval(time->time.time(document.refreshInterval()))
                        .numberOfShards(JsonData.of(document.shards()).toString())
                        .numberOfReplicas(JsonData.of(document.shards()).toString())
                )
                .mappings(typeMapping->typeMapping.withJson(readerMapping))
        );
        log.info("============索引库indexName：{}创建结果acknowledged：{}", indexName, createIndexResponse.acknowledged());
        return createIndexResponse.acknowledged();
    }

    @Override
    public boolean dropIndex(Class<T> clazz) throws Exception {
        String indexName = elasticSearchHelpUtils.getOnlyIndexName(clazz);
        DeleteIndexResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest->deleteIndexRequest.index(indexName));
        return deleteIndexResponse.acknowledged();
    }

}
